package com.baosight.risk.service.rire.impl;

import com.baosight.risk.api.rire.RiwaRiskWaringService;
import com.baosight.risk.base.service.BaseServiceImpl;
import com.baosight.risk.common.utils.StringUtils;
import com.baosight.risk.mapper.rire.RireRiskTargetMapper;
import com.baosight.risk.mapper.rire.RireRiskWarningStatusMapper;
import com.baosight.risk.mapper.riwa.RiwaRiskWaringMapper;
import com.baosight.risk.mapper.riwa.RiwaRiskWaringRuleMapper;
import com.baosight.risk.mapper.riwa.RiwaRiskWaringStatusMapper;
import com.baosight.risk.mapper.riwa.RiwaRiskWaringTargetMapper;
import com.baosight.risk.service.riim.entity.RiimRiskImport;
import com.baosight.risk.service.rire.entity.RireRiskTarget;
import com.baosight.risk.service.rire.entity.RireRiskWarningStatus;
import com.baosight.risk.service.riwa.entity.RiwaRiskWaring;
import com.baosight.risk.service.riwa.entity.RiwaRiskWaringRule;
import com.baosight.risk.service.riwa.entity.RiwaRiskWaringTarget;
import com.baosight.risk.service.zbaa.entity.ZbaaTarget;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class RiwaRiskWaringServiceImpl extends BaseServiceImpl<RiimRiskImport> implements RiwaRiskWaringService {
    @Autowired
    private RireRiskTargetMapper rireRiskTargetMapper;
    @Autowired
    private RireRiskWarningStatusMapper rireRiskWarningStatusMapper;
    @Autowired
    private RiwaRiskWaringTargetMapper riskWaringTatgetMapper;
    @Autowired
    private RiwaRiskWaringRuleMapper riskWaringRuleMapper;
    @Autowired
    private RiwaRiskWaringMapper riskWaringMapper;
    @Autowired
    private RiwaRiskWaringStatusMapper riskWaringStatusMapper;

    /**
     * 普通模型计算
     */
    @Override
    public RireRiskWarningStatus generalModelCalculate(String reportId) throws Exception {
        RireRiskWarningStatus rireRiskWarningStatus = rireRiskWarningStatusMapper.selectByPrimaryKey(reportId);
            if (null == rireRiskWarningStatus) {
                log.error("还不存在或者没有保存披露报告，无法预测结果");
                throw new Exception("还不存在或者没有保存披露报告，无法预测结果!");
            }
            //根据披露报告找到预警模型
            List<RiwaRiskWaring> waringList = riskWaringMapper.getWaringByImportId(rireRiskWarningStatus.getId());
            if (CollectionUtils.isEmpty(waringList)) {
                log.error("未找到预警模型，无法预测结果!");
                throw new Exception("还不存在或者没有保存披露报告，无法预测结果!");
            }
            //结果集合，可能满足多个结果
            List<String> resultList = new ArrayList<>();
            List<String> nextResultList = new ArrayList<>();
            List<RiwaRiskWaringRule> ruleList = riskWaringRuleMapper.getWaringRuleByReportId(rireRiskWarningStatus.getId());
            for (RiwaRiskWaringRule riskWaringRule : ruleList) {
                //根据规则找到具体的指标范围
                List<RiwaRiskWaringTarget> waringTargetList = riskWaringTatgetMapper.getWaringTargetByRuleId(riskWaringRule.getId());
                Map<String, Boolean> map = jisuan(waringTargetList, reportId);
                if (map.get("targetFlag")) {
                    resultList.add(riskWaringRule.getWarningStatus());
                }
                if (map.get("nextTargetFlag")) {
                    nextResultList.add(riskWaringRule.getWarningStatus());
                }
            }
            //下期预测结果
            if (CollectionUtils.isNotEmpty(nextResultList)) {
                rireRiskWarningStatus.setNextWaringStatus(result(nextResultList, "2"));
            }
//            //自定义预警
//            String warningType = waringList.get(0).getWarningType();
//            if (!"common".equals(warningType)) {
//                //本期预测结果
//                if (CollectionUtils.isEmpty(resultList)) {
//                    log.error("没有满足条件的预警规则，无法预测结果!");
//                    throw new Exception("没有满足条件的预警规则，无法预测结果!");
//                }
//
//            }
            rireRiskWarningStatus.setWaringStatus(result(resultList, "1"));
            //保存计算结果
            rireRiskWarningStatusMapper.updateByPrimaryKeySelective(rireRiskWarningStatus);
        return rireRiskWarningStatus;
    }

    public Map<String, Boolean> jisuan(List<RiwaRiskWaringTarget> waringTargetList, String reportId) throws Exception {
        List<Boolean> targetFlag = new ArrayList<>();
        List<Boolean> nextTargetFlag = new ArrayList<>();
        for (RiwaRiskWaringTarget waringTarget : waringTargetList) {
            List<RireRiskTarget> targetList = rireRiskTargetMapper.getByReportIdAndTargetNo(reportId, waringTarget.getCompCode(), waringTarget.getTargetNo());
            if (CollectionUtils.isEmpty(targetList)) {
                log.error("指标有误，在单位："+ waringTarget.getCompName() +"下没有找到指标:"+ waringTarget.getTargetName() +"，请检查风险指标和预警模型！");
                throw new Exception("指标有误，在单位："+ waringTarget.getCompName() +"下没有找到指标:"+ waringTarget.getTargetName() +"，请检查风险指标和预警模型！");
            } else if (targetList.size() > 1) {
                log.error("指标有误，该披露报告根据指标编码【" + waringTarget.getTargetNo() + "】找到多个关键指标！");
                throw new Exception("指标有误，该披露报告根据指标编码【" + waringTarget.getTargetNo() + "】找到多个关键指标！");
            }
            if (StringUtils.isNotEmpty(targetList.get(0).getTargetValue())) {
                BigDecimal targetValue = new BigDecimal(targetList.get(0).getTargetValue().trim());
                targetFlag.add(compare(targetValue, waringTarget));
            }

            if (StringUtils.isNotEmpty(targetList.get(0).getNextValue())) {
                BigDecimal nextTargetValue = new BigDecimal(targetList.get(0).getNextValue().trim());
                nextTargetFlag.add(compare(nextTargetValue, waringTarget));
            }

        }
        Map<String, Boolean> map = new HashMap();
        if (CollectionUtils.isNotEmpty(targetFlag)) {
            if (targetFlag.contains(false)) {
                map.put("targetFlag", false);
            } else {
                map.put("targetFlag", true);
            }
        } else {
            map.put("targetFlag", false);
        }
        if (CollectionUtils.isNotEmpty(nextTargetFlag)) {
            if (nextTargetFlag.contains(false)) {
                map.put("nextTargetFlag", false);
            } else {
                map.put("nextTargetFlag", true);
            }
        } else {
            map.put("nextTargetFlag", false);
        }
        return map;

    }

    public Boolean compare(BigDecimal targetValue, RiwaRiskWaringTarget waringTarget) {
        /*
         * compareTo:
         * -1：<
         * 0： =
         * 1： >
         * 0，-1： <=
         * 0，1：   >=
         */
        //上限标示，true表示计算通过
        Boolean maxFalg = false;
        //下限标示，true表示计算通过
        Boolean minFalg = false;

        if ("C".equals(waringTarget.getQuantityFlag())) {
            //指标值为值集
            if (waringTarget.getMaxLimit() != null && targetValue.compareTo(waringTarget.getMaxLimit()) == 0) {
                maxFalg = true;
                minFalg = true;
            }
        } else {
            //Y：包含，N：不包含
            //计算是否超过上限，下限为空时要计算，下限不为空时判断上限是否大于等于下限
            if (waringTarget.getMaxLimit() != null &&
                    (waringTarget.getMinLimit() == null || (waringTarget.getMinLimit() != null && waringTarget.getMaxLimit().compareTo(waringTarget.getMinLimit()) > -1))
            ) {
                if ("Y".equals(waringTarget.getMaxLimitMark())) {
                    //小于等于上限
                    if (targetValue.compareTo(waringTarget.getMaxLimit()) < 1) {
                        maxFalg = true;
                    }
                } else {
                    //小于上限
                    if (targetValue.compareTo(waringTarget.getMaxLimit()) < 0) {
                        maxFalg = true;
                    }
                }
            } else {
                maxFalg = true;
            }

            //计算是否低于下限
            //如果是Y，包含，如果是N，不包含
            if (waringTarget.getMinLimit() != null) {
                if ("Y".equals(waringTarget.getMinLimitMark())) {
                    //大于等于下限
                    if (targetValue.compareTo(waringTarget.getMinLimit()) > -1) {
                        minFalg = true;
                    }
                } else {
                    //大于下限
                    if (targetValue.compareTo(waringTarget.getMinLimit()) > 0) {
                        minFalg = true;
                    }
                }
            } else {
                minFalg = true;
            }
        }

        //结果都满足，给出结果
        if (maxFalg && minFalg) {
            return true;
        } else {
            return false;
        }
    }

    public String result(List<String> resultList, String flag) {
        //flag=1，本期预测，flag=2，下期预测
        String result = "";
        if (resultList.contains("black")) {
            result = "black";
            return result;
        } else if (resultList.contains("red")) {
            result = "red";
            return result;
        } else if (resultList.contains("orange")) {
            result = "orange";
//            System.out.println(result);
            return result;
        } else if (resultList.contains("yellow")) {
            result = "yellow";
            return result;
        } else {
            result = "green";
            return result;
        }
    }

    /**
     * 根据年度重点风险找到披露报告重的符合条件的指标
     *
     * @param acctYear   年度
     * @param compCode   组织结构
     * @param targetType 指标类型
     * @return
     */
    @Override
    public List<ZbaaTarget> getTargetByImport(String acctYear, String compCode, String targetType) {
        //找到所属公司

        List<ZbaaTarget> result = rireRiskTargetMapper.getTargetByImport(acctYear, compCode, targetType);
        return result;
    }
}
